const express = require('express')
const path = require('path')
// 路由加载
const mount = require('mount-routes')
// 解决跨域
const cors = require('cors')
// 访问不同的环境变量，scripts中配置启动方式
const dotenv = require('dotenv')
dotenv.config()
// 日志
const logger = require("./utils/utils.logger");
// 控制台颜色输出
const chalk = require('chalk')

const app = express()

// 处理?a=1&b=2方式的post请求
app.use(express.urlencoded({ extended: false }))
// 处理 body 类型的post请求
app.use(express.json())

// 数据库模型同步，如果数据库中没有models中定义的表，则在数据库中创建对应的表，应该用不到这一句
// const db = require("./models");
// db.sequelize.sync();

//解决跨域
app.use(cors())
// 设置跨域和相应数据格式
app.all('/api/*', function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, token')
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization')
  res.header('Content-Type', 'application/json;charset=UTF-8')
  res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With')
  res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
  if (req.method == 'OPTIONS') res.send(200)
  /*让options请求快速返回*/
  else next()
})

// 使用swagger API 文档
// https://www.npmjs.com/package/express-swagger-generator
const expressSwagger = require('express-swagger-generator')(app)
const options = require('./utils/swagger') //配置信息
expressSwagger(options)

// 统一响应机制
const UnifiedResponse = require('./utils/utils.resextra')
app.use(UnifiedResponse)

const admin_passport = require('./utils/utils.permission')

// 设置 passport 验证路径 ('/api/auth/' 开头的都需要进行token)
app.use('/api/auth/*', admin_passport.tokenAuth)

// 带路径的用法并且可以打印出路由表  true 代表展示路由表在打印台
mount(app, path.join(process.cwd(), '/routes'), true)

// 配置静态资源,静态资源需放在参数文件夹下
app.use(express.static('public'))

// 处理无响应 如果没有路径处理就返回 Not Found
// token 有效性中间件，处理无token时的异常
app.use(function (err, req, res, next) {
  if (err.name === 'UnauthorizedError') {
    logger.error(`${req.method} ${req.baseUrl + req.path} *** 响应：${JSON.stringify({
      data: null,
      code: err.status || 401,
      message: err.message || 'token错误'
    })}`);
    res.send({ data: null, code: 401, message: err.message || 'token错误' })
  } else if (err === '服务器内部错误') {
    res.status(500).sendResult({ data: null, code: 500, message: err })
  } else {
    console.log('====>', err)
    res.status(404).sendResult({ data: null, code: 404, message: 'Not Found' })
  }
})

app.listen(process.env.DEV_PORT, () => {
  console.log(chalk.bold.green(`项目启动成功: ${process.env.DEV_URL}:${process.env.DEV_PORT}`));
  console.log(chalk.bold.green(`接口文档地址: ${process.env.DEV_URL}:${process.env.DEV_PORT}/swagger`));
})